package com.saoft.fangcms.modules.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.saoft.fangcms.common.enums.StatusEnum;
import com.saoft.fangcms.modules.sys.entity.Menu;
import com.saoft.fangcms.modules.sys.mapper.MenuMapper;
import com.saoft.fangcms.modules.sys.service.MenuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author scc95599
 * @since 2019-12-24
 */
@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements MenuService {

    @Autowired
    MenuMapper menuMapper;

    @Override
    public List<Menu> getListBySortOk() {
        QueryWrapper<Menu> menuQueryWrapper = new QueryWrapper<Menu>().orderByAsc("type", "sort");
        menuQueryWrapper.eq("status", StatusEnum.OK.getCode());
        return menuMapper.selectList(menuQueryWrapper);
    }

    @Override
    public List<Menu> getListByPid(Long pid, Long notId) {
        QueryWrapper<Menu> menuQueryWrapper = new QueryWrapper<Menu>()
                .orderByAsc("sort");
        menuQueryWrapper.eq("pid", pid).notIn("id", notId);
        return menuMapper.selectList(menuQueryWrapper);
    }

    @Override
    public void save(List<Menu> levelMenu) {
        if (levelMenu != null) {
            levelMenu.forEach(menu -> {
                if (menu.getId() != null) {
                    menuMapper.updateById(menu);
                }else{
                    menu.setStatus(new Byte("1"));
                    menuMapper.insert(menu);
                }
            });
        }
    }

    @Override
    public Integer getSortMax(Long pid) {
        return menuMapper.findSortMax(pid);
    }

    /**
     * 根据状态和pid查找菜单
     * @param pid
     * @param status
     * @return
     */
    private List<Menu> findByPidsLikeAndStatus(Long pid,Byte status){
        QueryWrapper<Menu> menuQueryWrapper = new QueryWrapper<Menu>();
        menuQueryWrapper.like("pids", "%[" + pid + "]%");
        menuQueryWrapper.eq("status", status);
        return menuMapper.selectList(menuQueryWrapper);
    }

    /**
     * 更新菜单状态
     * @param statusEnum
     * @param ids
     * @return
     */
    @Override
    public boolean updateStatus(StatusEnum statusEnum, List<Long> ids) {
        // 获取与之关联的所有菜单
        Set<Menu> treeMenus = new HashSet<>();
        List<Menu> menus = findByIdIn(ids);
        menus.forEach(menu -> {
            treeMenus.add(menu);
            treeMenus.addAll(findByPidsLikeAndStatus(menu.getPid(), menu.getStatus()));
        });

        treeMenus.forEach(menu -> {
            // 删除菜单状态时，同时更新角色的权限
            if(statusEnum == StatusEnum.DELETE){
                // 删除相关权限
                menuMapper.cancelRoleJoin(menu.getId());
            }
            // 更新关联的所有菜单状态
            menu.setStatus(statusEnum.getCode());
            menuMapper.updateById(menu);
        });

        return treeMenus.size() > 0;
    }

    /**
     *
     * @param ids
     * @return
     */
    private List<Menu> findByIdIn(List<Long> ids) {
        QueryWrapper<Menu> menuQueryWrapper = new QueryWrapper<Menu>();
        menuQueryWrapper.in("id", ids);
        return menuMapper.selectList(menuQueryWrapper);
    }
}
